class AnonymousClassExtracter extends TreeParser;
		
options {
	importVocab = Java;		
}

{

}

statement: stat 

	|   #(n1:CTOR_CALL elist)
	
	|   #(n2:METHOD_CALL primaryExpression elist)
		      
	|  #(n3:SUPER_CTOR_CALL 
	        ( elist | 
		  primaryExpression { System.out.println("Anonymous class ex : primary expr no super");} elist ) )

        | #(FOR_INIT (variableDef | elist)?)
	
	| #(FOR_CONDITION (expression)?)
	
	| #(FOR_ITERATOR (elist)?)
		  
	;

stat:	// typeDefinition  { System.out.println("Classe local!!!!"); }

		variableDef

	|	expression 

	|	EMPTY_STAT 
	;

typeSpec
	:	#(TYPE typeSpecArray)
	;

typeSpecArray   
	:	#( ARRAY_DECLARATOR typeSpecArray )
	|	type
	;

type:	identifier 		
	|	builtInType
	;

builtInType
    :   "void"
    |   "boolean"
    |   "byte"
    |   "char"
    |   "short"
    |   "int"
    |   "float"
    |   "long"
    |   "double"
    ;

modifiers
	:	#( MODIFIERS (modifier)* )
	;

modifier
    :   "private"
    |   "public"
    |   "protected"
    |   "static"
    |   "transient"
    |   "final"
    |   "abstract"
    |   "native"
    |   "threadsafe"
    |   "synchronized"
    |   "const"
    |   "volatile"
	|	"strictfp"
    ;
    
variableDef    	
	:	#(VARIABLE_DEF modifiers typeSpec  variableDeclarator varInitializer)
	;

objectinitializer
	:	#(INSTANCE_INIT slist)
	;

variableDeclarator
	:	IDENT
	|	LBRACK variableDeclarator
	;

varInitializer 
	:	#(ASSIGN initializer)
	|
	;

initializer
	:	expression
	|	arrayInitializer
	;

arrayInitializer
	:	#(ARRAY_INIT initializer (initializer)* )
	;

identifier
	:	IDENT
	|	#(DOT identifier IDENT )
	;

slist
	:	#( SLIST (stat)* )
	;

tryBlock
	:	#( "try" slist (handler)* (#("finally" slist))? )
	;

handler
	:	#( "catch" parameterDef slist )

	;

parameterDef
	:	#(PARAMETER_DEF modifiers typeSpec IDENT)
	;

elist      
	:	#( ELIST (expression)* )
	;

expression
	:	#(EXPR expr)
	;

expr: 
	        #(QUESTION expr 
		           expr 
			   expr )

	|	#(ASSIGN expr 
	                 expr  )

	|	#(PLUS_ASSIGN expr 
			      expr )

	|	#(MINUS_ASSIGN expr
			       expr )

	|	#(STAR_ASSIGN expr 
			      expr )

	|	#(DIV_ASSIGN expr 
			     expr )

	|	#(MOD_ASSIGN  expr
			      expr )

	|	#(SR_ASSIGN expr
			    expr )

	|	#(BSR_ASSIGN  expr 
			      expr )

	|	#(SL_ASSIGN   expr 
			      expr )

	|	#(BAND_ASSIGN expr 
			      expr )

	|	#(BXOR_ASSIGN expr 
			      expr )

	|	#(BOR_ASSIGN  expr 
			      expr )

	|	#(LOR expr expr )

	|	#(LAND expr expr )

	|	#(BOR expr expr )

	|	#(BXOR expr expr )

	|	#(BAND expr expr )

	|	#(NOT_EQUAL expr expr )

	|	#(EQUAL expr expr )

	|	#(LT expr expr)

	|	#(GT expr expr )

	|	#(LE expr expr )

	|	#(GE expr expr )

	|	#(SL expr expr)

	|	#(SR expr expr )

	|	#(BSR expr expr )

	|	#(PLUS expr expr )

	|	#(MINUS expr expr)

	|	#(DIV expr expr )

	|	#(MOD expr expr )

	|	#(STAR expr expr )
	
	|	#(INC expr )

	|	#(DEC expr )

	|	#(POST_INC expr )

	|	#(POST_DEC expr )

	|	#(BNOT expr)

	|	#(LNOT expr )

	|	#("instanceof" expr
			       expr )

	|	#(UNARY_MINUS expr )

	|	#(UNARY_PLUS expr )

	|	primaryExpression

	;

primaryExpression

    :   IDENT

    |   #(	DOT 
			(	expr  

				(	IDENT 

				|	arrayIndex 

				|	"this" 

				|	"class"

				|	#( "new" IDENT elist )

				|   "super" 

				)
			|	#(ARRAY_DECLARATOR typeSpecArray)
			
			|	builtInType ("class")?

			)
		)

	|	arrayIndex

	|	#(METHOD_CALL primaryExpression elist)

	|	#(TYPECAST typeSpec expr )

	|   newExpression 

	|   constant 	
        |   "super" 	
        |   "true" 	
        |   "false" 	
        |   "this" 	
        |   "null" 

        |	// type name used with instanceof
		typeSpec 
	;

ctorCall
	:	#( CTOR_CALL elist )
	|	#( SUPER_CTOR_CALL
			(	elist
			|	primaryExpression elist
			)
		 )
	;

arrayIndex
	:	#(INDEX_OP primaryExpression expression )
	;

constant
    :   n1:NUM_INT
    |   n2:CHAR_LITERAL
    |   n3:STRING_LITERAL
    |   n4:NUM_FLOAT
    |   n5:NUM_DOUBLE
    |   n6:NUM_LONG
    ;

newExpression   
	:	#(	n1:"new" type
	
			(	
			        newArrayDeclarator 

				(arrayInitializer)?
			
			|	elist 
			        (OBJBLOCK {
				
				    System.out.println("Achei class Anonyma " + n1.toStringTree());
				    
				
				} )?)

			// (objBlock)? )
		)
	;

newArrayDeclarator
	:	#( ARRAY_DECLARATOR 

		       (newArrayDeclarator)? 

		       (expression )? )
	;
